#region Using

using System;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Collections.Generic;
using Jaws.Core.Web;
using Jaws.Core.Web.Entities;
using Jaws.Core.Web.Entities.Pages;

#endregion

namespace Jaws.Core.Web.HttpModules
{
    /// <summary>
    /// Handles pretty URL's and redirects them to the permalinks.
    /// </summary>
    public class UrlRewrite : IHttpModule
    {
        #region IHttpModule Members

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            // Nothing to dispose
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
        }

        #endregion

        /// <summary>
        /// Handles the BeginRequest event of the context control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void context_BeginRequest(object sender, EventArgs e)
        {
            HttpContext context = ((HttpApplication)sender).Context;
            string path = context.Request.Path.ToUpperInvariant();
            string url = context.Request.RawUrl.ToUpperInvariant();

            path = path.Replace(".ASPX.CS", "");
            url = url.Replace(".ASPX.CS", "");

            if (url.Contains(".aspx".ToUpperInvariant()) && !url.Contains("ERROR404.ASPX"))
            {
                if (path == Utils.RelativeWebRoot.ToUpperInvariant() + "DEFAULT.ASPX" && context.Request.QueryString.Count == 0)
                {
                    Page front = XmlCollectionBase<PageCollection, Page>.Load().GetHomePage();
                    if (front != null)
                        url = front.RelativeLink.ToUpperInvariant();
                }

                if (url.Contains("/PAGE/"))
                {
                    RewritePage(context, url);
                }
            }
        }

        private static void RewritePage(HttpContext context, string url)
        {
            string slug = ExtractTitle(context, url);
            var pages = XmlCollectionBase<PageCollection, Page>.Load();
            Page page = null;

            foreach (Page item in pages)
            {
                if (slug.Equals(Utils.RemoveIllegalCharacters(item.Slug), StringComparison.OrdinalIgnoreCase))
                {
                    page = item;
                }
            }
               

            if (page != null)
            {
                context.RewritePath(Utils.RelativeWebRoot + "default.aspx?pageid=" + page.Id + GetQueryString(context), false);
            }
        }

        private static void RewriteDefault(HttpContext context)
        {
            string url = context.Request.RawUrl;
            string page = "&page=" + context.Request.QueryString["page"];
            if (string.IsNullOrEmpty(context.Request.QueryString["page"]))
                page = null;

            context.RewritePath(url.Replace("Default.aspx", "default.aspx")); // fixes a casing oddity on Mono


        }

        /// <summary>
        /// Extracts the title from the requested URL.
        /// </summary>
        private static string ExtractTitle(HttpContext context, string url)
        {
            url = url.ToLowerInvariant().Replace("---", "-");
            if (url.Contains(".aspx") && url.EndsWith("/"))
            {
                url = url.Substring(0, url.Length - 1);
                context.Response.AppendHeader("location", url);
                context.Response.StatusCode = 301;
            }

            url = url.Substring(0, url.IndexOf(".aspx"));
            int index = url.LastIndexOf("/") + 1;
            string title = url.Substring(index);
            return context.Server.UrlEncode(title);
        }

        /// <summary>
        /// Gets the query string from the requested URL.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private static string GetQueryString(HttpContext context)
        {
            string query = context.Request.QueryString.ToString();
            if (!string.IsNullOrEmpty(query))
                return "&" + query;

            return string.Empty;
        }
    }
}